home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
pluginy Firefox
/
58189
/
58189.xpi
/
modules
/
DataService.jsm
< prev
next >
Wrap
Text File
|
2010-01-06
|
11KB
|
321 lines
/*
* The DataService is the Policy Information Point for requests. All the information
* is collected here. This information can be used to make decisions about the
* accpetance of certain requests.
*/
var EXPORTED_SYMBOLS = [ ];
Components.utils.import("resource://csfiremodules/CsFireCommon.jsm");
CsFire.DataService = new function() {
// Define the information stores
this.userRequests = new Array();
this.loadRequests = new Array();
this.httpRequests = new Array();
this.lastCheck = 0;
this.checkingTreshold = 5000;
this.removalTreshold = 5000;
}
/*
* Registers user interaction for a certain destination URI. The URI of the
* originating page is also registered.
*/
CsFire.DataService.registerUserInteraction = function(dst, src) {
/*
* Register data for later use. Since we only have a string URI, we'll
* use that to store the request information.
*/
var userData = {"dest": dst, "orig": src, "timestamp": new Date().getTime()};
CsFire.Logger.debug("Registering user interaction: " + dst);
this.userRequests[dst] = userData;
}
/*
* Registers a load request for a certain destination. The expected content type,
* originating page and context (DOM element) are also registered.
*/
CsFire.DataService.registerLoadRequest = function(dstUri, srcUri, contentType, context) {
var stringUri = dstUri.prePath + dstUri.path;
/*
* The browser has the tendency to submit load requests twice, so only register
* them the first time. The second time, we bail out.
*
* Caution: when using the "back"-button and then clicking a new link, the same Uri-object
* is used. Therefore, also check the string representation of the URIs to make sure
* we're dealing with the same request
*/
if(this.loadRequests[stringUri] != null) {
return;
}
// Split the destination URI and collect all load data
var dst = CsFire.HttpUtils.splitUri(dstUri);
var loadData = {"dst_uri": dstUri,
"dst_scheme": dst.scheme,
"dst_host": dst.host,
"dst_port": dst.port,
"dst_path": dst.path,
"dst_item": dst.item,
"params": dst.params,
"referrer_scheme": null,
"referrer_host": null,
"referrer_port": null,
"referrer_uri": null,
"type": contentType,
"node": null,
"timestamp": new Date().getTime()};
/*
* Try to set the referrer. Some sites do dirty things with JS, which causes
* mozilla to use "moz-nullprincipal" as a scheme
*/
if(srcUri.scheme != "moz-nullprincipal") {
loadData.referrer_uri = srcUri;
loadData.referrer_scheme = srcUri.scheme;
loadData.referrer_host = srcUri.host;
loadData.referrer_port = srcUri.port;
}
// Check the source DOM element of the request
try {
context.QueryInterface(Components.interfaces.nsIDOMNode);
loadData.node = context.nodeName;
}
catch(e) {}
/*
* Register data for later use. We have an URI object, which will be the same
* object with the HTTP request, so we can use that to store the load data.
*/
CsFire.Logger.debug("Registering load data: " + stringUri);
this.loadRequests[stringUri] = loadData;
}
/*
* This method registers all the necessary information about the HTTP request.
* All this information is available in the httpChannel object.
*
* Note: we can not check for auth headers here, since Firefox has not yet
* added cached credentials at this point.
*/
CsFire.DataService.registerHttpRequest = function(httpChannel) {
var stringUri = httpChannel.URI.prePath + httpChannel.URI.path;
// Split the destination URI and collect all http data
var dst = CsFire.HttpUtils.splitUri(httpChannel.URI);
var httpData = {"method": httpChannel.requestMethod,
"dst_scheme": dst.scheme,
"dst_host": dst.host,
"dst_port": dst.port,
"dst_path": dst.path,
"dst_item": dst.item,
"dst_uri": httpChannel.URI,
"params": dst.params,
"referrer_scheme": null,
"referrer_host": null,
"referrer_port": null,
"referrer_uri": null,
"redirect": false,
"cookies": [],
"timestamp": new Date().getTime()};
// Check referrer
if(httpChannel.referrer != null) {
var uri = CsFire.HttpUtils.splitUri(httpChannel.referrer);
httpData.referrer_uri = httpChannel.referrer;
httpData.referrer_scheme = uri.scheme;
httpData.referrer_host = uri.host;
httpData.referrer_port = uri.port;
}
// Check for redirects
if(httpChannel.originalURI != null && httpChannel.originalURI != httpChannel.URI) {
/*
* Redirects by means of the "Refresh" header or the HTML-tag pass through the "shouldLoad" method
* so they will be handled automatically. Redirects using the "Location" header don't, which is why we
* extract the necessary information here.
*/
var httpOrig = CsFire.HttpUtils.splitUri(httpChannel.originalURI);
httpData.redirect = true;
httpData.referrer_uri = httpChannel.originalURI;
httpData.referrer_scheme = httpOrig.scheme;
httpData.referrer_host = httpOrig.host;
httpData.referrer_port = httpOrig.port;
CsFire.Logger.debug("Detected redirect: " + httpChannel.originalURI.prePath + " ==> " + httpChannel.URI.prePath);
}
//Check for cookies and extract key names
httpData.cookies = CsFire.HttpUtils.extractCookies(httpChannel);
/*
* Register data for later use. We have an URI object, which is the same
* object as the load request, so we can use that to store the http data.
*/
CsFire.Logger.debug("Registering HTTP data: " + stringUri);
this.httpRequests[stringUri] = httpData;
}
/*
* Retrieves the data associated with this request and removes it from the stores.
*/
CsFire.DataService.getAndRemoveRequestData = function(uri) {
var stringUri = uri.prePath + uri.path;
var data = { "user": null, "load": null, "http": null };
// Collect the user data (string based URI)
data.user = this.userRequests[stringUri];
delete this.userRequests[stringUri];
// Collect the load data (URI)
data.load = this.loadRequests[stringUri];
delete this.loadRequests[stringUri];
// Collect the HTTP data (URI)
data.http = this.httpRequests[stringUri];
delete this.httpRequests[stringUri];
// Clean data stores
this._cleanDataStores();
// Check if we have found any info
if(data.user == null && data.load == null && data.http == null) {
/*
* Theoretically, this can occur if two simultaneous requests are
* processed at exactly the same time ...
* Practically: does not sem to occur
*/
data = null;
}
return this._combineData(data);
}
/*
* Checks the internal datastores for stale requests that can be removed.
* A timestamp is used to determine this (Configurable using variables in the
* constructor).
*/
CsFire.DataService._cleanDataStores = function() {
var time = new Date().getTime();
if(time - this.lastCheck > this.checkingTreshold) {
this.lastCheck = time;
var maxAge = time - this.removalTreshold;
this._cleanDataStore(this.userRequests, maxAge);
this._cleanDataStore(this.loadRequests, maxAge);
this._cleanDataStore(this.httpRequests, maxAge);
}
}
/*
* Checks the entries in the provided data store against the given max age. If
* an entry is too old, it is removed from the store.
*/
CsFire.DataService._cleanDataStore = function(store, maxAge) {
for(var index in store) {
var o = store[index];
if(o != null && o.timestamp != null && o.timestamp < maxAge) {
delete store[index];
}
}
}
/*
* This function combines data from all sources in to a single object, which can
* easily be used to make policy decisions
*/
CsFire.DataService._combineData = function(data) {
// Extract the different parts
var user = data.user;
var load = data.load;
var http = data.http;
// Define the combined data object
var comb = {"dst_scheme": null,
"dst_host": null,
"dst_port": null,
"dst_uri": null,
"referrer_scheme": null,
"referrer_host": null,
"referrer_port": null,
"referrer_uri": null,
"dst_path": null,
"dst_item": null,
"params": null,
"type": null,
"node": null,
"method": null,
"redirect": false,
"cookies": null,
"user_initiated": false };
// Extract common data between load and http
var extractedCommon = false;
if(load != null && http != null) {
extractedCommon = true;
// Extract common data
load.dst_scheme == null ? comb.dst_scheme = http.dst_scheme : comb.dst_scheme = load.dst_scheme;
load.dst_host == null ? comb.dst_host = http.dst_host : comb.dst_host = load.dst_host;
load.dst_port == null ? comb.dst_port = http.dst_port : comb.dst_port = load.dst_port;
load.dst_item == null ? comb.dst_item = http.dst_item : comb.dst_item = load.dst_item;
load.dst_uri == null ? comb.dst_uri = http.dst_uri : comb.dst_uri = load.dst_uri;
load.dst_path == null ? comb.dst_path = http.dst_path : comb.dst_path = load.dst_path;
load.params == null ? comb.params = http.params : comb.params = load.params;
load.referrer_scheme == null ? comb.referrer_scheme = http.referrer_scheme : comb.referrer_scheme = load.referrer_scheme;
load.referrer_host == null ? comb.referrer_host = http.referrer_host : comb.referrer_host = load.referrer_host;
load.referrer_port == null ? comb.referrer_port = http.referrer_port : comb.referrer_port = load.referrer_port;
load.referrer_uri == null ? comb.referrer_uri = http.referrer_uri : comb.referrer_uri = load.referrer_uri;
}
// Extract user specific data
if(user != null) {
comb.user_initiated = true;
}
// Extract load specific data
if(load != null) {
comb.type = load.type;
comb.node = load.node;
if(!extractedCommon) {
comb.dst_scheme = load.dst_scheme;
comb.dst_host = load.dst_host;
comb.dst_port = load.dst_port;
comb.referrer_scheme = load.referrer_scheme;
comb.referrer_host = load.referrer_host;
comb.referrer_port = load.referrer_port;
comb.referrer_uri = load.referrer_uri;
comb.dst_item = load.dst_item;
comb.params = load.params;
}
}
// Extract http specific data
if(http != null) {
comb.method = http.method;
comb.redirect = http.redirect;
comb.cookies = http.cookies;
if(!extractedCommon) {
comb.dst_scheme = http.dst_scheme;
comb.dst_host = http.dst_host;
comb.dst_port = http.dst_port;
comb.referrer_scheme = http.referrer_scheme;
comb.referrer_host = http.referrer_host;
comb.referrer_port = http.referrer_port;
comb.referrer_uri = http.referrer_uri;
comb.dst_item = http.dst_item;
comb.params = http.params;
}
}
return comb;
}